home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh -- need to mention perl here to avoid recursion
- 'true' || eval 'exec perl -S $0 $argv:q';
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec /usr/bin/perl -S $0 $argv:q'
- if 0;
-
- # Usage: ftp.chk
- #
- # This shell script checks to see if you've set up (mainly anonymous)
- # ftp correctly. There seems to be some different types of ftp's
- # around; for instance, some allow "chmod" -- and if the home dir is
- # owned by "ftp", you're toast. So I've tried to err on the side of
- # safety...
- #
- # See the man page for a more detailed description, here's what this
- # checks for:
- #
- # - User ftp exists in the password file.
- # - root (or all root equivalents) are in ftpusers file.
- # - Home directory for ftp should exist, and not be /
- # - The ~ftp/etc/{passwd|group} should not be the same as the real ones.
- # - Various critical files/directories should exist, and have correct
- # permissions and owners; variables "$primary" and "$secondary" can be set
- # to whomever you want owning the files:
- #
- # File/Dir Perms Owner Other
- # ========= ====== ====== ======
- # ~ftp non-w.w. root
- # or
- # ~ftp 555 ftp if no chmod command exists
- #
- # All of these are ftp owned iff no chmod exists...
- #
- # ~ftp/bin non-w.w. root/ftp
- # ~ftp/bin/ls 111 root/ftp
- # ~ftp/etc non-w.w. root/ftp
- # ~ftp/etc/passwd non-w.w. root/ftp 0 size or nonexistant
- # ~ftp/etc/group non-w.w. root/ftp 0 size or nonexistant
- # ~ftp/pub non-w.w. root/ftp
- # ~ftp/incoming world-writable root/ftp This can be set to "pub"
- # ~ftp/.rhosts non-w.w. root 0 size, is optional
- # ~ftp/* non-w.w. other dirs/files in ~ftp
- #
- #
-
- require 'is_able.pl';
- require 'file_mode.pl';
- require 'glob.pl';
- require 'fgrep.pl';
- require 'pass.cache.pl';
- require 'file_owner.pl';
- require 'pathconf.pl';
-
- $CMP="/bin/cmp" unless defined $CMP;
-
- package ftp;
-
- # Primary and secondary owners of the ftp files/dirs; if you *don't* have
- # chmod, you can probably change the secondary owner to "ftp". If you have
- # chmod in your ftp, definitely have secondary to some other account (root
- # is fine for this.)
- $primary = "root" unless defined $primary;
- $secondary = "ftp" unless defined $secondary;
-
- # some might have this as ftpd; is the account in /etc/passwd
- $ftpuid = "ftp";
-
- # system files
- $ftpusers = "/etc/ftpusers";
- $passwd = $'PASSWD || "/etc/passwd";
- $group = $'GROUP || "/etc/group";
-
- # ftp's home:
- $ftproot = &'uname2dir($ftpuid);
- $anonymous = $ftproot ne '';
-
- $ftprhosts = "$ftproot/.rhosts";
- $ftpbin = "$ftproot/bin";
- $ftpls = "$ftpbin/ls";
- $ftpetc = "$ftproot/etc";
- $ftppasswd = "$ftpetc/passwd";
- $ftpgroup = "$ftpetc/group";
-
- $W = 'Warning! ' unless defined $W;
-
- # the pub/incoming stuff; by default, pub is *not* world writable, incoming
- # is; if you want pub to be world writable, just change incoming to "pub"
- $incoming = "pub";
-
- @crit_files=($ftpgroup,
- $ftppasswd,
- $ftpls);
-
- if (-s $ftpusers) {
- # check to see if root (or root equivalents) is in ftpusers file
- @all_roots = split(" ", $'uid2names{0});
- for $i (@all_roots) {
- if (length($user2passwd{$i}) == 13 && ! &'fgrep($ftpusers, "^$i$")) {
- print "Warning! $i should be in $ftpusers!\n";
- }
- }
- }
-
- # do the anonymous ftp checking stuff now?
- die unless $anonymous;
-
- # if the user ftp doesn't exist, no-anon stuff....
- # if $TEST -z $ftproot -a "$anonymous" = "yes" ; then
-
- die "${W}Need user $ftpuid for anonymous ftp to work!\n" if ($ftpuid eq "");
-
- # if the user ftp doesn't exist, no-anon stuff....
- if (! -d $ftproot || $ftproot eq "") {
- die "${W}Home directory for ftp doesn\'t exist!\n";
- }
- if ($ftproot eq "/") {
- print qq:${W}$ftproot ftp's home directory should not be "/"!\n:;
- }
-
- # want to check all the critical files and directories for correct
- # ownership. Some versions of ftp don't need much of anything... no
- # etc directory or password/group files.
- # others need etc directory & password/group files. Experiment.
- #
- push(@crit_files, $ftpbin, $ftpetc);
- for $i (@crit_files) {
- $owner = &'Owner($i);
-
- if ($owner eq 'BOGUS') {
- print "${W}Critical anon-ftp file $i is missing!\n";
- next;
- }
-
- $owner = $'uid2names{$owner};
-
- if ($owner !~ /\b$primary\b|\b$secondary\b/) {
- print "${W}$i should be owned by $primary or $secondary, not $owner!\n";
- }
- }
-
- # Don't want the passwd and group files to be the real ones!
- if (&'Owner($ftppasswd) ne 'BOGUS' &&
- $passwd ne $ftppasswd &&
- ! system "$CMP -s $passwd $ftppasswd")
- {
- print "${W}$ftppasswd and $passwd are the same!\n";
- }
-
- if (&'Owner($ftpgroup) ne 'BOGUS' &&
- $group ne $ftpgroup &&
- ! system "$CMP -s $passwd $ftpgroup")
- {
- print "${W}$ftpgroup and $group are the same!\n";
- }
-
- # ftproot is special; if owned by root; should be !world writable;
- # if owned by ftp, should be mode 555
-
- if (&'Owner($ftproot) ne 'BOGUS') {
- $owner = $'uid2names{&'Owner($ftproot)};
- $perms=&'Mode($ftproot);
- if ($owner !~ /\b$primary\b|\b$secondary\b/) {
- print "${W}$ftproot should be owned by $primary or $secondary, not $owner!\n";
- }
-
- # ftp-root should not be world-writable:
- &'is_able($ftproot, "w", "w");
-
- # if ftp owns root-dir, then mode should be 555:
- if ($owner eq $ftpuid && $perms ne 00555) {
- print "${W}$ftproot should be mode 555!\n";
- }
- }
-
- #
- # check the .rhosts file:
- if (-f $ftprhosts) {
- if (-s $ftprhosts) {
- print "${W}$ftprhosts should be be empty!\n";
- }
- $owner=$'uid2names{&'Owner($ftprhosts)};
- if ($owner ne $primary && $owner ne $secondary) {
- print "${W}$ftprhosts should be owned by $primary or $secondary!\n";
- }
- }
-
- # finally, some permissions of miscellaneous files:
- if (($perms=&'Mode($ftpls)) & 0666) {
- printf "${W}Incorrect permissions (%04o) on $ftpls!\n", $perms;
- }
-
- if (($perms=&'Mode($ftppasswd)) & 0333) {
- printf "${W}Incorrect permissions (%04o) on $ftppasswd!\n", $perms;
- }
-
-
- if (($perms=&'Mode($ftpgroup)) & 0333) {
- printf "${W}Incorrect permissions (%04o) on $ftpgroup!\n", $perms;
- }
-
- # Finally, the ~ftp/{pub|incoming|whatever} stuff:
- opendir(FTPDIR, $ftproot) || die "can't opendir $ftproot: $!\n";
-
- @all_dirs=grep(-d, readdir(FTPDIR));
-
- local($is_able'silent) = 1;
- for $i (@all_dirs) {
- if ($i ne $incoming && &'is_able($ftproot . "/$i", "w", "w")) {
- print "${W}Anon-ftp directory $i is World Writable!\n";
- }
- }
-
- 1;
- # end of script
-